package com.isunland.managesystem.service;

/**
 * 、
 * 后台定位
 * Created by wangyanan on 2016/8/29.
 */

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import android.text.format.DateFormat;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.isunland.managesystem.R;
import com.isunland.managesystem.common.ApiConst;
import com.isunland.managesystem.common.MyApplication;
import com.isunland.managesystem.common.RequestManager;
import com.isunland.managesystem.entity.CurrentUser;
import com.isunland.managesystem.ui.AttendancePagerActivity;
import com.isunland.managesystem.utils.LogUtil;
import com.isunland.managesystem.utils.MyUtils;
import com.isunland.managesystem.utils.SharedPreferencesUtil;
import java.util.HashMap;
import java.util.Map;

public class LocationService extends Service {
  private static final String TAG = "LocationService";
  private static final int NET_ERROR = 111;
  private static Notification mNotification;
  //public static final String PREF_IS_ALARM_ON = "isAlarmOn";
  public AMapLocationClient mLocationClient;
  private MyLocationListener mLocationListener;
  private WakeLock mWakeLock;
  /**
   * 上次更新的时间,是在考勤打卡中点击保持轨迹的时间.
   */
  private long mLastUpdateTimeMillis = SharedPreferencesUtil.getLong(MyApplication.getAppContext(),
      SharedPreferencesUtil.LAST_AUTO_SIGN_MILLIS, 0);
  /**
   * 服务器给定的间隔时间
   */
  private long mInternalTime = SharedPreferencesUtil.getInt(MyApplication.getAppContext(),
      SharedPreferencesUtil.INTERNAL_TIME, 30 * 60 * 1000);
  //private Resources mRes=MyApplication.getAppContext().getResources();

  /**
   * 每隔一分钟调用一次,用于防止数据无效.
   *
   * @param flags START_FLAG_REDELIVERY
   */
  @Override public int onStartCommand(Intent intent, int flags, int startId) {
    LogUtil.i(TAG, "onStartCommand-----------------");
    //初始化定位
    if (mLocationClient == null) {
      initLocationClient();
    }
    //启动定位,isStarted判断无效.
    if (!mLocationClient.isStarted()) {
      mLocationClient.startLocation();
      LogUtil.i("startLocation");
    }
    if (mNotification == null) {
      Initnotifycation();
    }
    startForeground(1, mNotification);

    //Must be one or more of: Service.START_FLAG_REDELIVERY, Service.START_FLAG_RETRY
    return super.onStartCommand(intent, START_FLAG_REDELIVERY, startId);
  }

  @Override public void onCreate() {
    LogUtil.i(TAG, "oncreate-----------------");
    acquireWakeLock();
    //初始化通知
    Initnotifycation();
    // 把当前服务设定为前台服务，并指定显示的通知。
    startForeground(1, mNotification);
    //初始化定位
    initLocationClient();
    // 启动定位
    mLocationClient.startLocation();
    LogUtil.i("startLocation");
    super.onCreate();
  }

  /**
   * 初始化高德定位.
   */
  protected void initLocationClient() {
    mLocationListener = new MyLocationListener();
    mLocationClient = new AMapLocationClient(this.getApplicationContext());
    AMapLocationClientOption locationOption = new AMapLocationClientOption();
    // 设置定位模式为高精度模式
    locationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Battery_Saving);
    locationOption.setNeedAddress(true);

    LogUtil.i("InternalTime=" + mInternalTime);
    //alarm一分钟唤醒一次定位,location一分钟定位一次,服务端返回间隔时间上传数据.
    locationOption = locationOption.setInterval(60 * 1000);
    // 设置定位监听
    mLocationClient.setLocationListener(mLocationListener);
    // 设置定位参数
    mLocationClient.setLocationOption(locationOption);
    LogUtil.i("InitLocationClient");
  }

  /**
   * service绑定通知,并设置为前台进程.
   */
  private void Initnotifycation() {
    // 声明一个通知，并对其进行属性设置
    NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(LocationService.this).setSmallIcon(R.drawable.ic_launcher)
            //.setLargeIcon(BitmapFactory.decodeResource(mRes, R.drawable.ic_launcher))
            .setContentTitle(getResources().getString(R.string.hint_start_location_service))
            .setContentText(getResources().getString(R.string.hint_setting_location_service))
            // 设置无法取消
            .setOngoing(true);

    // 声明一个Intent，用于设置点击通知后开启的Activity
    Intent resuliIntent = new Intent(LocationService.this, AttendancePagerActivity.class);
    PendingIntent resultPendingIntent =
        PendingIntent.getActivity(LocationService.this, 0, resuliIntent,
            PendingIntent.FLAG_CANCEL_CURRENT);
    mBuilder.setContentIntent(resultPendingIntent);
    mNotification = mBuilder.build();
    LogUtil.i("initNotification");
  }

  /**
   * 无网络连接和打卡失败的提示.
   */
  private Notification InitnotifycationNetError() {
    // 声明一个通知，并对其进行属性设置
    NotificationCompat.Builder builder =
        new NotificationCompat.Builder(LocationService.this).setSmallIcon(R.drawable.ic_launcher)
            //.setLargeIcon(BitmapFactory.decodeResource(mRes, R.drawable.ic_launcher))
            .setContentTitle(getResources().getString(R.string.error_sign_keep_title))
            .setContentText(getResources().getString(R.string.error_sign_keep_message,
                DateFormat.format("HH:mm", System.currentTimeMillis()).toString()))
            .setAutoCancel(true);

    // 声明一个Intent，用于设置点击通知后开启的Activity
    Intent intent = new Intent(LocationService.this, AttendancePagerActivity.class);
    PendingIntent resultPendingIntent = PendingIntent.getActivity(LocationService.this, 0, intent,
        PendingIntent.FLAG_CANCEL_CURRENT);
    builder.setContentIntent(resultPendingIntent);
    LogUtil.i("initNotificationErrorNetwork");
    return builder.build();
  }

  @Override public void onDestroy() {
    mLocationClient.stopLocation();
    mLocationClient.unRegisterLocationListener(mLocationListener);
    RequestManager.cancelAll(this);

    // 在服务销毁的时候，使当前服务推出前台，并销毁显示的通知
    stopForeground(true);
    releaseWakeLock();
    super.onDestroy();
  }

  private void volleyPost(AMapLocation location) {
    if (location == null || location.getErrorCode() != 0) {
      showErrorNotification();
      return;
    }
    if (!MyUtils.isNetLink(this)) {
      showErrorNotification();
      return;
    }

    StringRequest request = getStringRequest(location);
    request.setRetryPolicy(RequestManager.getRetryPolicy());
    RequestManager.getRequestQueue(this).add(request);
  }

  /**
   * 显示错误通知并电铃屏幕
   */
  private void showErrorNotification() {
    Notification notification = InitnotifycationNetError();
    //startForeground(NET_ERROR,notification);//会和外勤轨迹的重合,之后被覆盖掉.
    NotificationManager manager = (NotificationManager) MyApplication.getAppContext()
        .getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(NET_ERROR, notification);
    WakeLock wakeLock = lightScreen();
    if (wakeLock != null) wakeLock.release();
  }

  @Override public IBinder onBind(Intent intent) {
    return null;
  }

  private StringRequest getStringRequest(final AMapLocation location) {
    ApiConst.getHostFromSharedPre(getApplicationContext());
    return new StringRequest(Method.POST, ApiConst.getAbsoluteUrl(ApiConst.URL_SIGN_OUT),
        responseListener(), errorListener()) {

      protected Map<String, String> getParams() {

        HashMap<String, String> params = new HashMap<>();
        //经纬度有效时时,传递经纬度.

        params.put("latitude", location.getLatitude() + "");
        params.put("longitude", location.getLongitude() + "");

        //位置有效时传递位置.
        params.put("location", location.getAddress());

        params.put("checkType", "keep");
        params.put("outId", SharedPreferencesUtil.getString(MyApplication.getAppContext(),
            SharedPreferencesUtil.OUT_ID, ""));
        params.put("remark", "");
        params.put("regJobNo", CurrentUser.newInstance(LocationService.this).getJobNumber());
        params.put("memberCode", CurrentUser.newInstance(LocationService.this).getMemberCode());
        LogUtil.i(TAG, "url=" + ApiConst.getAbsoluteUrl(ApiConst.URL_SIGN));
        LogUtil.i(TAG, "params=" + params.toString());
        return params;
      }

      //@Override
      //public Map<String, String> getHeaders() throws AuthFailureError {
      //    HashMap<String, String> headers = new HashMap<>();
      //    String cookieString = SharedPreferencesUtil.getString(
      //            MyApplication.getAppContext(), SharedPreferencesUtil.COOKIE,
      //            "");
      //    headers.put("Cookie", cookieString);
      //    // LogUtil.i(TAG, "cookie=" + cookieString);
      //    return headers;
      //}
    };
  }

  private Response.Listener<String> responseListener() {
    return new Response.Listener<String>() {

      @Override public void onResponse(String arg0) {
        //不在这里更新,因为在执行网络请求的时间,可能会有多次的定位,打卡响应后更新上次打卡时间.
        //SharedPreferencesUtil.setLong(LocationService.this, SharedPreferencesUtil.LAST_AUTO_SIGN_MILLIS, System.currentTimeMillis());
        LogUtil.i("response=" + arg0);
      }
    };
  }

  public Response.ErrorListener errorListener() {
    return new Response.ErrorListener() {
      @Override public void onErrorResponse(VolleyError error) {
        LogUtil.e(TAG, "volleyError=" + error.toString(), error);
        showErrorNotification();
      }
    };
  }

  // //获取电源锁，保持该服务在屏幕熄灭时仍然获取CPU时，保持运行
  private void acquireWakeLock() {
    if (null == mWakeLock) {
      PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
      mWakeLock =
          pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "");
      if (null != mWakeLock) {
        mWakeLock.acquire();
      }
    }
  }

  /**
   * 点亮屏幕
   */
  private WakeLock lightScreen() {
    WakeLock wakeLock = null;
    try {
      PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
      //noinspection deprecation
      wakeLock =
          powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
              "neterror");
      wakeLock.acquire();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return wakeLock;
  }

  // 释放设备电源锁
  private void releaseWakeLock() {
    if (null != mWakeLock) {
      mWakeLock.release();
      mWakeLock = null;
    }
  }

  public class MyLocationListener implements AMapLocationListener {

    @Override public void onLocationChanged(AMapLocation location) {
      //if (location == null || location.getErrorCode() != 0) {
      //
      //    return;
      //}

      //double latitude = location.getLatitude();
      //double longtitude = location.getLongitude();

      //LogUtil.i(TAG, "latitude=" + latitude + ",longtitude=" + longtitude);
      //由于isStart判断不起作用,startLocation每隔一分钟会执行一次,所以在这里增加限制,小于服务端给定的间隔则不再执行联网操作.
      if ((System.currentTimeMillis() - mLastUpdateTimeMillis) >= mInternalTime) {

        //更新最近一次更新时间为当前时间.避免多条记录,所以不能在Volleypost响应中执行.
        mLastUpdateTimeMillis = System.currentTimeMillis();

        volleyPost(location);
      }

      //

    }
  }
}
